package sky.cin.framework.ioms.registry.client;

import sky.cin.framework.extension.log.Croog;
import sky.cin.framework.ioms.common.entities.LoadBalance;
import sky.cin.framework.network.HTTP;
import sky.cin.framework.network.dto.HttpServletRequest;
import sky.cin.framework.network.http.Response;
import sky.cin.framework.network.nio.ServerUtils;
import sky.cin.framework.sfoc.core.annotations.beans.Autowired;
import sky.cin.framework.sfoc.core.annotations.beans.Config;
import sky.cin.framework.sfoc.core.annotations.beans.Value;
import sky.cin.framework.sfoc.core.interfaces.InitializingBean;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;

@Config
public class InitializingRegistryClient implements InitializingBean {
    
    @Autowired
    private Croog logger;
    
    @Value("${server.name}")
    private String serverName;
    
    @Value("${server.port}")
    private Integer port;
    
    @Value("${registry.host}")
    private String registryHost;
    
    @Value("${registry.port}")
    private Integer registryPort;

    @Value("${server.load-balance}")
    private String loadBalance;

    public static final Integer WAIT = 5000;

    private Selector selector = null;

    private SocketChannel socketChannel = null;

    @Override
    public void afterPropertiesSet() {
        try {
            selector = Selector.open();
            socketChannel = SocketChannel.open(new InetSocketAddress(registryHost, registryPort));
            socketChannel.configureBlocking(false);
            socketChannel.register(selector, SelectionKey.OP_READ);

            LoadBalance balance = this.loadBalance == null
                    ? LoadBalance.POLLING
                    : LoadBalance.valueOf(loadBalance.toUpperCase());
            String url = String.format("/registry/login?name=%s&balance=%s", serverName, balance.name());
            HttpServletRequest request = new HttpServletRequest(url);
            request.setHeader("Host", String.format("%s:%d", HTTP.LOCAL_HOST, port));

            Response response = ServerUtils.doInvoke(socketChannel, request, selector);
            if (response.getData().equals("true")) {
                logger.info(String.format("已注册到服务注册中心 [%s:%d]", registryHost, registryPort));
            } else {
                logger.info(String.format("服务注册中心 [%s:%d] 中已存在本服务", registryHost, registryPort));
            }
            new Thread(this::sendHeart).start();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }
    }

    private void sendHeart() {
        while (true) {
            try {
                Thread.sleep(WAIT);
                HttpServletRequest request = new HttpServletRequest("/registry/heart");
                request.setHeader("Host", String.format("%s:%d", HTTP.LOCAL_HOST, port));
                ServerUtils.sendRequest(socketChannel, request);
            } catch (Exception e) {
                logger.info("完蛋，你服务器挂了");
                try {
                    socketChannel.close();
                    selector.close();
                    System.exit(0);
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
            }

        }
    }

}